﻿using UnityEngine;
using System;
using System.Collections;
using Pumpkin.FrameBase;
using Pumpkin.Utils;
/*
	可以理解为插件的入口模块
	在这个入口中安装了需要监听的事件(installEvents)，同时初始化KBEngine(initKBEngine)
*/

namespace KBEngine
{
    public class KBEConfigs
    {
        public string ip;
        public int port;
        public int clientType;
        public int networkEncryptType;
        public int syncPlayerMS;
        public int threadUpdateHZ;
        public int serverHeartbeatTick;
        public UInt32 TCP_SEND_BUFFER_MAX;
        public UInt32 TCP_RECV_BUFFER_MAX;
        public UInt32 UDP_SEND_BUFFER_MAX;
        public UInt32 UDP_RECV_BUFFER_MAX;
        public bool useAliasEntityID;
        public bool isOnInitCallPropertysSetMethods;
        public bool forceDisableUDP;
        public bool isMultiThreads;

        public int getTCPRecvBufferSize()
        {
            return (int)TCP_RECV_BUFFER_MAX;
        }

        public int getTCPSendBufferSize()
        {
            return (int)TCP_SEND_BUFFER_MAX;
        }

        public int getUDPRecvBufferSize()
        {
            return (int)UDP_RECV_BUFFER_MAX;
        }

        public int getUDPSendBufferSize()
        {
            return (int)UDP_SEND_BUFFER_MAX;
        }
    }

    public class KBEMain : MonoBehaviour, IModuleComponent
    {
        public enum CLIENT_TYPE
        {
            // Mobile(Phone, Pad)
            CLIENT_TYPE_MOBILE = 1,

            // Windows Application program
            CLIENT_TYPE_WIN = 2,

            // Linux Application program
            CLIENT_TYPE_LINUX = 3,

            // Mac Application program
            CLIENT_TYPE_MAC = 4,

            // Web，HTML5，Flash
            CLIENT_TYPE_BROWSER = 5,

            // bots
            CLIENT_TYPE_BOTS = 6,

            // Mini-Client
            CLIENT_TYPE_MINI = 7,
        };

        //加密通信类型
        public enum NETWORK_ENCRYPT_TYPE
        {
            //无加密
            ENCRYPT_TYPE_NONE = 0,

            //Blowfish
            ENCRYPT_TYPE_BLOWFISH = 1,
        };

        public KBEngineApp gameapp = null;

        // 在unity3d界面中可见选项
        public DEBUGLEVEL debugLevel = DEBUGLEVEL.DEBUG;
        public bool isMultiThreads = false;
        public string ip = "127.0.0.1";
        public int port = 20013;
        public CLIENT_TYPE clientType = CLIENT_TYPE.CLIENT_TYPE_MINI;
        public NETWORK_ENCRYPT_TYPE networkEncryptType = NETWORK_ENCRYPT_TYPE.ENCRYPT_TYPE_NONE;
        public int syncPlayerMS = 1000 / 10;

        public int threadUpdateHZ = 10 * 2;
        public int serverHeartbeatTick = 60;
        public int TCP_SEND_BUFFER_MAX = (int)KBEngine.NetworkInterfaceBase.TCP_PACKET_MAX;
        public int TCP_RECV_BUFFER_MAX = (int)KBEngine.NetworkInterfaceBase.TCP_PACKET_MAX;
        public int UDP_SEND_BUFFER_MAX = (int)KBEngine.NetworkInterfaceBase.UDP_PACKET_MAX;
        public int UDP_RECV_BUFFER_MAX = (int)KBEngine.NetworkInterfaceBase.UDP_PACKET_MAX;
        public bool useAliasEntityID = true;
        public bool isOnInitCallPropertysSetMethods = true;
        public bool forceDisableUDP = false;
        public IFrameModule module_;

        protected virtual void Awake()
        {
        }

        public void SetModule(IFrameModule module)
        {
            module_ = module;
        }

        // Use this for initialization
        protected virtual void Start()
        {
            MonoBehaviour.print("clientapp::start()");
            installEvents();
            initKBEngine();
            Log.LogInfo("Init KBEngine finish", LogColor.Yellow);
            module_.OnLoaded();
        }

        public virtual void installEvents()
        {
        }

        public virtual void initKBEngine()
        {
            // 如果此处发生错误，请查看 Assets\Scripts\kbe_scripts\if_Entity_error_use______git_submodule_update_____kbengine_plugins_______open_this_file_and_I_will_tell_you.cs

            Dbg.debugLevel = debugLevel;

            KBEConfigs args = new KBEConfigs();

            args.ip = ip;
            args.port = port;
            args.clientType = (int)clientType;
            args.networkEncryptType = (int)networkEncryptType;
            args.syncPlayerMS = syncPlayerMS;
            args.threadUpdateHZ = threadUpdateHZ;
            args.serverHeartbeatTick = serverHeartbeatTick / 2;
            args.useAliasEntityID = useAliasEntityID;
            args.isOnInitCallPropertysSetMethods = isOnInitCallPropertysSetMethods;
            args.forceDisableUDP = forceDisableUDP;

            args.TCP_SEND_BUFFER_MAX = (UInt32)TCP_SEND_BUFFER_MAX;
            args.TCP_RECV_BUFFER_MAX = (UInt32)TCP_RECV_BUFFER_MAX;
            args.UDP_SEND_BUFFER_MAX = (UInt32)UDP_SEND_BUFFER_MAX;
            args.UDP_RECV_BUFFER_MAX = (UInt32)UDP_RECV_BUFFER_MAX;

            args.isMultiThreads = false;

            //if(isMultiThreads)
            //	gameapp = new KBEngineAppThread(args);
            //else
            //  gameapp = new KBEngineApp(args);
            new KBEngine.Event();
            new KBEngine.Messages();

            gameapp = new KBEngineApp(args);
            //向热更新模块发送参数
            gameapp.InitializeApp(args);
        }

        protected virtual void OnDestroy()
        {
            MonoBehaviour.print("clientapp::OnDestroy(): begin");
            if (KBEngineApp.app != null)
            {
                KBEngineApp.app.destroy();
                KBEngineApp.app = null;
            }
            KBEngine.Event.clear();
            MonoBehaviour.print("clientapp::OnDestroy(): end");
        }

        protected virtual void FixedUpdate()
        {
            KBEUpdate();
        }

        public virtual void KBEUpdate()
        {
            // 单线程模式必须自己调用
            //if(!isMultiThreads)
            //gameapp.process();
            KBEngine.Event.processBuildinEvents();
            if (KBEngineApp.app.networkInterface != null)
            {
                KBEngineApp.app.networkInterface.process();
            }
            gameapp.process();
        }
    }

}

